﻿namespace Pub.Class
{
    using System;
    using System.IO;
    using System.Security.Cryptography;
    using System.Text;

    public class SymmetryCryptor : ISymmetryCryptor
    {
        private System.Text.Encoding encoding = System.Text.Encoding.Default;
        private byte[] initialVector;
        private const string strInitialVector = "SymmetryCryptor";
        private SymmetricAlgorithm symmetricAlgorithm;
        private Pub.Class.SymmetricAlgorithmType symmetricAlgorithmType;

        public byte[] DecryptStream(byte[] bytesEncoded, string key)
        {
            byte[] buffer2;
            if (bytesEncoded.IsNull())
            {
                return null;
            }
            byte[] bytes = this.encoding.GetBytes(key);
            MemoryStream stream = new MemoryStream(bytesEncoded);
            CryptoStream stream2 = new CryptoStream(stream, this.symmetricAlgorithm.CreateDecryptor(bytes, this.initialVector), CryptoStreamMode.Read);
            try
            {
                string s = new StreamReader(stream2, this.encoding).ReadToEnd();
                buffer2 = this.encoding.GetBytes(s);
            }
            finally
            {
                stream.Close();
                stream2.Close();
            }
            return buffer2;
        }

        public byte[] DecryptStream(byte[] bytesEncoded, int offset, int toDecrpyLen, string key)
        {
            byte[] buffer = this.GetPartOfStream(bytesEncoded, offset, toDecrpyLen);
            return this.DecryptStream(buffer, key);
        }

        public string DecryptString(string strEncoded, string key)
        {
            byte[] bytesEncoded = Convert.FromBase64String(strEncoded);
            byte[] bytes = this.DecryptStream(bytesEncoded, key);
            return this.encoding.GetString(bytes, 0, bytes.Length);
        }

        public byte[] EncryptStream(byte[] source, string key)
        {
            byte[] buffer3;
            if (source.IsNull())
            {
                return null;
            }
            byte[] bytes = this.encoding.GetBytes(key);
            MemoryStream stream = new MemoryStream();
            CryptoStream stream2 = new CryptoStream(stream, this.symmetricAlgorithm.CreateEncryptor(bytes, this.initialVector), CryptoStreamMode.Write);
            try
            {
                stream2.Write(source, 0, source.Length);
                stream2.FlushFinalBlock();
                buffer3 = stream.ToArray();
            }
            finally
            {
                stream.Close();
                stream2.Close();
            }
            return buffer3;
        }

        public byte[] EncryptStream(byte[] source, int offset, int toEncrpyLen, string key)
        {
            if (toEncrpyLen == 0)
            {
                return source;
            }
            byte[] buffer = this.GetPartOfStream(source, offset, toEncrpyLen);
            return this.EncryptStream(buffer, key);
        }

        public string EncryptString(string source, string key)
        {
            byte[] bytes = this.encoding.GetBytes(source);
            return Convert.ToBase64String(this.EncryptStream(bytes, key));
        }

        private byte[] GetExactBytes(string source, int length)
        {
            byte[] buffer = new byte[length];
            byte[] bytes = this.encoding.GetBytes(source);
            int num = bytes.Length;
            if (num >= length)
            {
                for (int j = 0; j < length; j++)
                {
                    buffer[j] = bytes[j];
                }
                return buffer;
            }
            for (int i = 0; i < length; i++)
            {
                buffer[i] = bytes[i % num];
            }
            return buffer;
        }

        private byte[] GetPartOfStream(byte[] source, int offset, int length)
        {
            if (source.IsNull() || (offset >= source.Length))
            {
                return null;
            }
            if ((length + offset) > source.Length)
            {
                length = source.Length - offset;
            }
            byte[] buffer = new byte[length];
            for (int i = 0; i < length; i++)
            {
                buffer[i] = source[offset + i];
            }
            return buffer;
        }

        public void Initialize(CipherMode mode)
        {
            this.initialVector = this.GetExactBytes("SymmetryCryptor", 0x10);
            switch (this.symmetricAlgorithmType)
            {
                case Pub.Class.SymmetricAlgorithmType.DES:
                    this.symmetricAlgorithm = new DESCryptoServiceProvider();
                    break;

                case Pub.Class.SymmetricAlgorithmType.RC2:
                    this.symmetricAlgorithm = new RC2CryptoServiceProvider();
                    break;

                case Pub.Class.SymmetricAlgorithmType.Rijndael:
                    this.symmetricAlgorithm = new RijndaelManaged();
                    break;

                case Pub.Class.SymmetricAlgorithmType.TripleDES:
                    this.symmetricAlgorithm = new TripleDESCryptoServiceProvider();
                    break;

                default:
                    this.symmetricAlgorithm = new DESCryptoServiceProvider();
                    break;
            }
            this.symmetricAlgorithm.Mode = mode;
        }

        public System.Text.Encoding Encoding
        {
            get
            {
                return this.encoding;
            }
            set
            {
                this.encoding = value;
            }
        }

        public Pub.Class.SymmetricAlgorithmType SymmetricAlgorithmType
        {
            get
            {
                return this.symmetricAlgorithmType;
            }
            set
            {
                this.symmetricAlgorithmType = value;
            }
        }
    }
}

